package main

import "fmt"

func main() {
	//golang中，可以把函数当做变量使用
	getSumFuncVal := getSum
	result := getSumFuncVal(1, 2)
	fmt.Println("result=", result)

	sum, sub := getSumAndSub(1, 2)
	fmt.Println("sum=", sum, "sub=", sub)

	sum = doSomething(getSumFuncVal, 10, 20)
	fmt.Println("sum=", sum)

	sum = doSomething2(getSum, 100, 100)
	fmt.Println("sum=", sum)

	var n1 MyByte = 10
	fmt.Println(n1)

	var n2 MyByte = 255
	n1 = MyByte(n2) //必须强制类型转换，因为虽然MyByte就是byte，但是对于golang就是不同的类型
	fmt.Println(n1)

	totalSum := getTotalSum(5, 1)
	fmt.Println(totalSum)
}

//golang中，若多个形参类型相同，前面部分可以省略参数类型
func getSum(n1, n2 int32) int32 {
	return n1 + n2
}

//golang中返回值可以定义名称，直接给定义的返回值赋值就可以不用return的时候指定返回值了，
//这样可以避免顺序问题,当然，return的时候是可以带上返回内容的，不影响
func getSumAndSub(n1, n2 int32) (sum int32, sub int32) {
	sum = n1 + n2
	sub = n1 - n2
	return
	// return sum, sub //这样也可以
	// return 1, 2 //这样也可以
}

//函数可以当做形参使用
func doSomething(myFunc func(int32, int32) int32, num1 int32, num2 int32) (sum int32) {
	sum = myFunc(num1, num2)
	return
}

//上面这种方式：myFunc func(int32, int32) int32
//写起来可能会很长，golang中支持自定义数据类型（对类型取别名）
//如下：MyByte就等于是byte
//注意只是实际数据类型相同，但是实际上是不同的类型，导致不可以直接把byte的值赋值给MyByte
type MyByte byte

//定义一个自定义类型，等同于func(int32, int32) (sum int32)
type myTestFunc func(int32, int32) (sum int32)

//依然把函数当做形参，但是这次用的是自定义类型
func doSomething2(myFunc myTestFunc, num1 int32, num2 int32) (sum int32) {
	sum = myFunc(num1, num2)
	return
}

//golang支持可变参数
//nums是一个int32的切片，所谓切片就是可变数组
func getTotalSum(num int32, nums ...int32) (totalSum int32) {
	totalSum = num
	for i := 0; i < len(nums); i++ {
		totalSum += nums[i]
	}
	return
}
